package cn.tuling.example;

import java.util.ArrayList;
import java.util.List;

/**
 * 安全模式实现：
 * <p>
 * 用组合模式实现当用户在商店购物后，显示其所选商品信息，并计算所选商品总价的功能。
 * <p>
 * 说明：假如李先生到韶关“天街e角”生活用品店购物，
 * 用 1 个红色小袋子装了 2 包婺源特产（单价 7.9 元）、1 张婺源地图（单价 9.9 元）；
 * 用 1 个白色小袋子装了 2 包韶关香藉（单价 68 元）和 3 包韶关红茶（单价 180 元）；
 * 用 1 个中袋子装了前面的红色小袋子和 1 个景德镇瓷器（单价 380 元）；
 * 用 1 个大袋子装了前面的中袋子、白色小袋子和 1 双李宁牌运动鞋（单价 198 元）。
 * <p>
 * 最后“大袋子”中的内容有：{1 双李宁牌运动鞋（单价 198 元）、
 * 白色小袋子{2 包韶关香菇（单价 68 元）、3 包韶关红茶（单价 180 元）}、
 * 中袋子{1 个景德镇瓷器（单价 380 元）、红色小袋子{2 包婺源特产（单价 7.9 元）、1 张婺源地图（单价 9.9 元）}}
 * }
 * 现在要求编程显示李先生放在大袋子中的所有商品信息并计算要支付的总价。
 */
public class ShopTest {
    public static void main(String[] args) {
        Bags redSmallBag, whiteSmallBag, middleBag, bigBag;
        redSmallBag = new Bags("红色小袋子");
        whiteSmallBag = new Bags("白色小袋子");
        middleBag = new Bags("中袋子");
        bigBag = new Bags("大袋子");

        redSmallBag.add(new Goods("婺源特产", 7.9f, 2));
        redSmallBag.add(new Goods("婺源地图", 9.9f, 1));

        whiteSmallBag.add(new Goods("韶关香藉", 68f, 2));
        whiteSmallBag.add(new Goods("韶关红茶", 180f, 3));

        middleBag.add(redSmallBag);
        middleBag.add(new Goods("景德镇瓷器", 380f, 1));

        bigBag.add(middleBag);
        bigBag.add(whiteSmallBag);
        bigBag.add(new Goods("李宁牌运动鞋", 198f, 1));

        bigBag.show();
        System.out.println("总价：" + bigBag.calculate());
    }
}

// 抽象构件
interface Articles {
    void show();

    float calculate();
}

// 树叶构件
class Goods implements Articles {
    private String name;
    private float unitPrice;
    private int quantity;

    public Goods(String name, float unitPrice, int quantity) {
        this.name = name;
        this.unitPrice = unitPrice;
        this.quantity = quantity;
    }

    @Override
    public void show() {
        System.out.println(name + "(数量：" + quantity + "，单价：" + unitPrice + "元)");
    }

    @Override
    public float calculate() {
        return unitPrice * quantity;
    }
}

// 树枝构件
class Bags implements Articles {
    private String name;
    private List<Articles> children = new ArrayList<>();

    public Bags(String name) {
        this.name = name;
    }

    public void add(Articles articles) {
        children.add(articles);
    }

    @Override
    public void show() {
        for (Articles child : children) {
            child.show();
        }
    }

    @Override
    public float calculate() {
        float totalPrice = 0f;
        for (Articles child : children) {
            totalPrice = totalPrice + child.calculate();
        }
        return totalPrice;
    }
}
